<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>继承与多态</title>
</head>
<body>
    
</body>
</html>

<script>

    /*
    //使用Object.create 创建对象  作为  Admin,Member 的原型来实现继承
    //实际上来说  继承就是使用父级的方法和属性  而自己又有自己的方法和属性

    //定义一个User构造方法
    function User(){}
    //给这个构造方法增加属性方法
    User.prototype.getName = function(){};

    //创建一个Admin构造方法
    function Admin(){};
    //改变Admin构造方法的原型
    Admin.prototype = Object.create(User.prototype);
    Admin.prototype.role = function(){};

    //创建一个Member构造方法
    function Member(){};
    Member.prototype = Object.create(User.prototype);
    Member.prototype.email = function(){};

    console.log(new Admin());
    console.log(new Member());
    */



    //不能使用下面的方式操作，因为这样会改变User的原型方法，这不是继承，是改变对象的原型   是没有错误的，只是不是继承
    // function User(){};
    // User.prototype.getUserName = function(){};

    // function Admin(){};
    // Admin.prototype = User.prototype;
    // Admin.prototype.role = function(){};

    // console.log(new Admin());



    //构造函数
    //有多种方式通过构造函数创建对象

    // function Admin(){}

    // //构造方法其实就是指向当前对象  也就是当前方法的实现
    // console.log(Admin == Admin.prototype.constructor);

    // let hd = new Admin.prototype.constructor();
    // console.log(hd);

    // let xj = new Admin();
    // console.log(xj);


    // function User(){}

    // function Admin(){}

    // //设置了Admin的原型之后   丢失了自己的构造方法
    // Admin.prototype = Object.create(User.prototype);
    // Admin.prototype.role = function(){};

    // let xj = new Admin();

    // console.log(xj.constructor);

    // //所以当要继承的别的对象的时候   需要再次设置constructor属性
    // Admin.prototype.constructor = Admin;

    // let hd = new Admin();

    // console.log(hd.constructor);


    //使用Object.defineProperty 定义来禁止遍历constructor属性
    // function User(){};

    // function Admin(name){
    //     this.name = name;
    // }

    // Admin.prototype = Object.create(User.prototype);
    // Object.defineProperty(Admin.prototype,"constructor",{
    //     value:Admin,
    //     enumerable:false//禁止遍历
    // });

    // let hd = new Admin("后盾人");
    // for(const key in hd){
    //     console.log(key)
    // }

    //完全重写构造函数原型,只对后面的对象有效
    // function User(){

    // }
    // const lisi = new User();
    // User.prototype = {
    //     constructor : User,
    //     show(){
    //         return "property show";
    //     }
    // };

    // const wangwu = new User();
    // console.log(wangwu.show());
    // console.log(lisi.show());

    /*

    //方法重写
    //下面展示的是子类需要重写父类的方法
    function Person(){}

    Person.prototype.getName = function(){
        console.log('parent method');
    }

    function User(name){

    }

    User.prototype = Object.create(Person.prototype);
    User.prototype.constructor = User;

    //重写
    //当前对象中如果有这个方法的话，就不会去追朔原型上的方法
    //也就实现了重写
    User.prototype.getName = function(){
        //调用父级同名方法
        Person.prototype.getName.call(this);
        console.log("child method");
    }

    let hd = new User();
    hd.getName();

    */

    //多态
    //根据多种不同的形态产生不同的结果
    function User(){};
    User.prototype.show = function(){
        console.log(this.description());
    }

    function Admin(){};
    Admin.prototype = Object.create(User.prototype);
    Admin.prototype.description = function(){
        return '管理员在此';
    }

    function Member(){};
    Member.prototype = Object.create(User.prototype);
    Member.prototype.description = function(){
        return '我是会员';
    }


    function Enterprise(){};
    Enterprise.prototype = Object.create(User.prototype);
    Enterprise.prototype.description = function(){
        return '企业账户';
    }

    for(const obj of [new Admin(),new Member(),new Enterprise()]){
        obj.show();
    }








</script>